
/*
 * @author kanghua(kanghua151@msn.com) 
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <glib.h>
#include "hlfs.h"
#include "comm_define.h"
#include "misc.h"
#include "logger.h"


int hlfs_read(struct hlfs_ctrl *ctrl, char* read_buf, uint32_t read_len, uint64_t pos){

#if 0
    if( (pos+read_len) > ctrl->inode.length){
        g_message("%s - read out of fs cur length:%lld \n",__func__,ctrl->inode.length);
        return 0;
    }
#endif 
    int ret = 0;
    int start_db = 0;
    guint32 BLOCKSIZE = ctrl->sb.block_size;
    if(pos/BLOCKSIZE == (pos+read_len)/BLOCKSIZE){
       g_message("%s - only need to read one block:%llu\n",__func__,pos/BLOCKSIZE);
       char *block;
       if(-1==(ret=load_block_by_addr(ctrl,pos,&block))){
           g_message("%s - fail to load block for addr %llu\n",__func__,pos);
           return -1;
       }else if(1==ret){
           block = (char*)g_malloc0(BLOCKSIZE);
       }
       memcpy(read_buf,block + pos%BLOCKSIZE,read_len);
       g_free(block);
       return read_len;
    }

    g_message("%s - need to read muti block\n",__func__);
    uint32_t offset=0; 
    if( pos % BLOCKSIZE != 0 ){
       g_message("%s - need to read first block\n",__func__);
       char *block;
       if(-1==(ret=load_block_by_addr(ctrl,pos,&block))){
           g_message("%s - fail to load block for addr %llu\n",__func__,pos);
           return -1;
       }else if(1 == ret){
           block = (char*)g_malloc0(BLOCKSIZE);
       }
       memcpy(read_buf,block + pos%BLOCKSIZE, BLOCKSIZE - pos%BLOCKSIZE);
       offset += BLOCKSIZE - pos%BLOCKSIZE;
       g_message("offset:%u\n",offset);
       g_free(block);
       start_db = ( pos + BLOCKSIZE )/BLOCKSIZE;
    }else{
       start_db = pos/BLOCKSIZE;
    }

    int end_db =   (pos + read_len)/BLOCKSIZE;
    g_message("%s - start db:%d end db:%d\n",__func__,start_db,end_db);
    int i;
    for(i = start_db; i < end_db;i++){
        char *block;
        if(-1==(ret=load_block_by_no(ctrl,i,&block))){
           g_message("%s - fail to load block for no %d\n",__func__,i);
           return -1;
        }else if(1==ret){
           block = (char*)g_malloc0(BLOCKSIZE);
        }
        memcpy(read_buf+offset,block,BLOCKSIZE);
        offset +=BLOCKSIZE;
        g_message("offset:%u\n",offset);
        g_free(block);
    }

    if((pos + read_len )% BLOCKSIZE != 0 ){
       g_message("%s - need to read last block\n",__func__);
       char *block;
       if(-1==(ret=load_block_by_addr(ctrl,pos+read_len,&block))){
           g_message("%s - fail to load block for addr %llu\n",__func__,pos + read_len);
           return -1;
       }else if (1==ret){
           block = (char*)g_malloc0(BLOCKSIZE);
       }
       memcpy(read_buf + offset , block , (pos + read_len)%BLOCKSIZE );
       offset +=(pos+read_len)%BLOCKSIZE;
       g_message("offset:%u\n",offset);
       g_free(block);
    } 
    g_message("read len %u\n",offset);
    return offset;
}
